SUBROUTINE TableGetFloat &
!
( valueIn, tab, keyIn, keyOut, match, valueOut, bound )
! Module used:
USE StringManipulation, ONLY: &
! imported routines:
StringCompact, StringToUpper, StringToFloat, ToString
USE LogLib, ONLY : &
! Imported Routines:
Catch
USE ErrorCodes, ONLY : &
! Imported parameters:
unknownOption
IMPLICIT NONE
! Function arguments
! Scalar arguments with intent(in):
REAL (KIND = float), INTENT (IN) :: valueIn
CHARACTER (LEN = *), INTENT (IN) :: keyIn
CHARACTER (LEN = *), INTENT (IN) :: keyOut
CHARACTER (LEN = *), INTENT (IN) :: match
CHARACTER (LEN = *), OPTIONAL, INTENT (IN) :: bound
! Type defined arguments with intent (in):
TYPE (Table), INTENT (IN) :: tab
! Scalar arguments with intent(out):
REAL (KIND = float), INTENT (OUT) :: valueOut
! Local scalars:
TYPE (Column), POINTER :: colIn
TYPE (Column), POINTER :: colOut
INTEGER (KIND = short) :: i
CHARACTER (LEN = 100) :: string
LOGICAL :: foundValue
REAL (KIND = float) :: upperIn
REAL (KIND = float) :: lowerIn
REAL (KIND = float) :: upperOut
REAL (KIND = float) :: lowerOut
REAL (KIND = float) :: bias
!------------end of declaration------------------------------------------------
!inizialization
foundValue = .FALSE.
!find columns to be processed
DO i = 1, tab % noCols
string = StringCompact (StringToUpper (tab % col (i) % header) )
IF ( string == StringToUpper(keyIn) ) THEN
colIn => tab % col (i) !colIn is an alias of the input column
ELSE IF ( string == StringToUpper(keyOut) ) THEN
colOut => tab % col (i) !colOut is an alias of the output column
END IF
END DO
SELECT CASE ( StringToUpper (match) )
CASE ('EXACT')
!bound method is not necessary, only fixed makes sense.
DO i = 1, tab % noRows
IF ( StringToFloat (colIn % row (i)) == valueIn ) THEN
foundValue = .TRUE.
valueOut = StringToFloat (colout % row (i))
END IF
END DO
IF ( .NOT. foundValue ) THEN
CALL Catch ('error', 'TableLib', &
TRIM ( ToString (valueIn) ) // ' not found in table: ' , &
argument = tab % id )
END IF
CASE ('LINEAR')
!if bound is not specified, assume FIXED
IF (.NOT. PRESENT (bound) ) THEN
IF ( StringToFloat (colIn % row (1)) > valueIn .OR. &
StringToFloat (colIn % row (tab % noRows) ) < valueIn ) THEN
CALL Catch ('error', 'TableLib', 'bounds exceeded in table: ', &
argument = TRIM(tab % Id) )
END IF
!search for upper and lower value to interpolate between
DO i = 1, tab % noRows
IF ( StringToFloat (colIn % row (i)) <= valueIn .AND. &
StringToFloat (colIn % row (i+1)) >= valueIn ) THEN
lowerIn = StringToFloat ( colIn % row (i) )
upperIn = StringToFloat ( colIn % row (i+1) )
lowerOut = StringToFloat ( colOut % row (i) )
upperOut = StringToFloat ( colOut % row (i+1) )
EXIT
END IF
END DO
valueOut = LinearInterp ( lowerIn, upperIn, lowerOut, upperOut, valueIn )
ELSE
SELECT CASE ( StringToUpper (bound) )
CASE ('FIXED')
IF ( StringToFloat (colIn % row (1)) > valueIn .OR. &
StringToFloat (colIn % row (tab % noRows) ) < valueIn ) THEN
CALL Catch ('error', 'TableLib', 'bounds exceeded in table: ', &
argument = TRIM(tab % Id) )
END IF
!search for upper and lower value to interpolate between
DO i = 1, tab % noRows
IF ( StringToFloat (colIn % row (i)) <= valueIn .AND. &
StringToFloat (colIn % row (i+1)) >= valueIn ) THEN
lowerIn = StringToFloat ( colIn % row (i) )
upperIn = StringToFloat ( colIn % row (i+1) )
lowerOut = StringToFloat ( colOut % row (i) )
upperOut = StringToFloat ( colOut % row (i+1) )
EXIT
END IF
END DO
valueOut = LinearInterp ( lowerIn, upperIn, lowerOut, upperOut, valueIn )
CASE ('EXTENDLINEAR')
!If value exceed lower bound
IF ( StringToFloat (colIn % row (1)) >= valueIn ) THEN
lowerIn = StringToFloat ( colIn % row (1) )
upperIn = StringToFloat ( colIn % row (2) )
lowerOut = StringToFloat ( colOut % row (1) )
upperOut = StringToFloat ( colOut % row (2) )
!calculate interpolation
valueOut = LinearInterp ( lowerIn, upperIn, lowerOut, upperOut, valueIn )
CALL Catch ('warning', 'TableLib', &
'value is under lower bound: extending linearly')
!if value exceed upper bound
ELSE IF ( StringToFloat (colIn % row (tab % noRows)) <= valueIn ) THEN
lowerIn = StringToFloat ( colIn % row ( tab % noRows - 1) )
upperIn = StringToFloat ( colIn % row ( tab % noRows ) )
lowerOut = StringToFloat ( colOut % row ( tab % noRows - 1) )
upperOut = StringToFloat ( colOut % row ( tab % noRows ) )
!calculate interpolation
valueOut = LinearInterp ( lowerIn, upperIn, lowerOut, upperOut, valueIn )
CALL Catch ('warning', 'TableLib', &
'value is over upper bound: extending linearly')
ELSE !value is between the boundary of the table
!search for upper and lower value to interpolate between
DO i = 1, tab % noRows
IF ( StringToFloat (colIn % row (i)) <= valueIn .AND. &
StringToFloat (colIn % row (i+1)) >= valueIn ) THEN
lowerIn = StringToFloat ( colIn % row (i) )
upperIn = StringToFloat ( colIn % row (i+1) )
lowerOut = StringToFloat ( colOut % row (i) )
upperOut = StringToFloat ( colOut % row (i+1) )
EXIT
END IF
END DO
valueOut = LinearInterp ( lowerIn, upperIn, lowerOut, upperOut, valueIn )
END IF
CASE ('EXTENDCONSTANT')
!If value exceed lower bound
IF ( StringToFloat (colIn % row (1)) >= valueIn ) THEN
valueOut = StringToFloat (colOut % row (1))
CALL Catch ('warning', 'TableLib', &
'value is under lower bound: extending constantly')
!if value exceed upper bound
ELSE IF ( StringToFloat (colIn % row (tab % noRows)) <= valueIn ) THEN
valueOut = StringToFloat (colOut % row (tab % noRows))
CALL Catch ('warning', 'TableLib', &
'value is over upper bound: extending constantly')
ELSE !value is between the boundary of the table
!search for upper and lower value to interpolate between
DO i = 1, tab % noRows
IF ( StringToFloat (colIn % row (i)) <= valueIn .AND. &
StringToFloat (colIn % row (i+1)) >= valueIn ) THEN
lowerIn = StringToFloat ( colIn % row (i) )
upperIn = StringToFloat ( colIn % row (i+1) )
lowerOut = StringToFloat ( colOut % row (i) )
upperOut = StringToFloat ( colOut % row (i+1) )
EXIT
END IF
END DO
valueOut = LinearInterp ( lowerIn, upperIn, lowerOut, upperOut, valueIn )
END IF
CASE DEFAULT
CALL Catch ('error', 'TableLib', &
'unknown option in call to TableGetValue: ' , &
code = unknownOption, argument = TRIM(bound) )
END SELECT
END IF
CASE ('NEAREST')
!bound method is not necessary, only fixed makes sense.
bias = HUGE (bias) !initializa bias to biggest number
DO i = 1, tab % noRows
IF ( ABS ( StringToFloat (colIn % row (i)) - valueIn ) < bias ) THEN
bias = ABS ( StringToFloat (colIn % row (i)) - valueIn )
valueOut = StringToFloat (colOut % row (i))
END IF
END DO
CASE DEFAULT
CALL Catch ('error', 'TableLib', &
'unknown option in call to TableGetValue: ' , &
code = unknownOption, argument = TRIM(match) )
END SELECT
END SUBROUTINE TableGetFloat